package cn.tedu.curator;

import org.apache.curator.RetryPolicy;
import org.apache.curator.framework.CuratorFramework;
import org.apache.curator.framework.CuratorFrameworkFactory;
import org.apache.curator.framework.recipes.cache.TreeCache;
import org.apache.curator.framework.recipes.cache.TreeCacheEvent;
import org.apache.curator.retry.ExponentialBackoffRetry;
import org.apache.zookeeper.CreateMode;
import org.apache.zookeeper.data.Stat;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;

import java.util.HashMap;
import java.util.List;
import java.util.Map;

// Curator是Apache提供的操作Zookeeper的客户端框架
// 提供了对Zookeeper的基本操作以及一些高级特性
public class CuratorDemo {

    private CuratorFramework client;

    // 开启客户端
    @Before
    public void startClient() {
        // 指定重试策略
        // baseSleepTimeMs - 间隔时间
        // maxRetries - 最大的重试次数
        // 如果没有连接成功，那么每隔3s重试一次，最多重试5次
        RetryPolicy rp =
                new ExponentialBackoffRetry(3000, 5);
        // 获取客户端
        client = CuratorFrameworkFactory.newClient("10.42.77.153:2181", rp);
        // 开启客户端
        client.start();
    }

    // 创建节点
    @Test
    public void createNode() throws Exception {
        client.create().creatingParentsIfNeeded()
                .withMode(CreateMode.PERSISTENT)
                .forPath("/txt/t1", "test".getBytes());
    }

    // 修改数据
    @Test
    public void setData() throws Exception {
        Stat stat = client.setData().withVersion(-1)
                .forPath("/log", "hello".getBytes());
        System.out.println(stat);
    }

    // 获取数据
    @Test
    public void getData() throws Exception {
        byte[] data = client.getData().forPath("/log");
        System.out.println(new String(data));
    }

    // 获取子节点
    @Test
    public void getChildren() throws Exception {
        List<String> cs = client.getChildren().forPath("/");
        for (String c : cs) {
            System.out.println(c);
        }
    }

    // 删除节点
    @Test
    public void deleteNode() throws Exception {
        // 要求没有子节点
        // client.delete().forPath("/log");
        // 递归删除
        client.delete().deletingChildrenIfNeeded().forPath("/txt");
    }

    // 判断节点是否存在
    @Test
    public void exist() throws Exception {
        Stat stat = client.checkExists().forPath("/txt");
        System.out.println(stat);
    }
    // 监听机制
    @Test
    public void watch () throws Exception {
        TreeCache cache = new TreeCache(client,"/log");
        // 获取监听器
        cache.getListenable().addListener((c ,t) -> {
            TreeCacheEvent.Type type = t.getType();
            switch (type) {
                case NODE_ADDED:
                    System.out.println("节点被创建");
                    break;
                case NODE_REMOVED:
                    System.out.println("节点被移除");
                    break;
                case NODE_UPDATED:
                    System.out.println("节点被修改");
                    break;
                default:
                    System.out.println("其他操作被触发");
            }
        });
        // 开始监听过程
        cache.start();
        while (true);

    }
    @Test
    public void test01(){
        Map map = new HashMap<>();
        map.put(1,"w");
        System.out.println(map.get(1));
    }
    // 关闭客户端
    @After
    public void closeClient() {
        if (client != null) client.close();
    }


}
